home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- ** Test Color Index Lighting
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <X11/Xlib.h>
- #include <X11/keysym.h>
- #include <GL/gl.h>
- #include <GL/glx.h>
-
- float indexScale = 1.0;
-
- int useLighting = 0;
- int useTwoSide = 0;
- int useLocalLight = 0;
- int useLocalViewer = 0;
- int useSpot = 0;
- int useAtten = 0;
- int whichObject = 0;
-
- float modelAmb[4] = { 0.0, 0.0, 0.0, 0.0 };
-
- float lightPosInf[4] = { 0.0, 0.0, 1.0, 0.0 };
- float lightPosLoc[4] = { 0.0, 0.0, 4.0, 1.0 };
- float lightAmb[4] = { 0.2, 0.2, 0.2, 0.0 };
- float lightDiff[4] = { 0.6, 0.6, 0.6, 0.0 };
- float lightSpec[4] = { 0.2, 0.2, 0.2, 0.0 };
- float lightSpotDir[3] = { 0.0, 0.0, -1.0 };
- float lightSpot[2] = { 100.0, 30.0 };
- float lightAtten[3] = { 0.80, 0.25, 0.05 };
-
- float matIndexRange[3] = { 0.05, 0.75, 0.95 };
- float matIndexes[3] = { 0.0, 0.0, 0.0 };
- float matShininess[1] = { 10.0 };
-
- static void
- init(void)
- {
- glClearIndex(0.0);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(-1, 1, -1, 1, 1, 3);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0.0, 0.0, -2.0);
-
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_NORMALIZE);
-
- glLineWidth(2.0);
- }
-
- static void
- reconfig(void)
- {
- glLightModelfv(GL_AMBIENT, modelAmb);
- glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, useLocalViewer);
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, useTwoSide);
-
- glLightfv(GL_LIGHT0, GL_POSITION, useLocalLight ? lightPosLoc:lightPosInf);
- glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff);
- glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);
- glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightSpotDir);
- glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, useSpot ? lightSpot[0]:1.0);
- glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, useSpot ? lightSpot[1]:180.0);
- glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, useAtten ? lightAtten[0]:1.0);
- glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, useAtten ? lightAtten[1]:0.0);
- glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, useAtten ? lightAtten[2]:0.0);
- glEnable(GL_LIGHT0);
-
- matIndexes[0] = matIndexRange[0]*indexScale;
- matIndexes[1] = matIndexRange[1]*indexScale;
- matIndexes[2] = matIndexRange[2]*indexScale;
- glMaterialfv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES, matIndexes);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, matShininess);
-
- if (useLighting) {
- glEnable(GL_LIGHTING);
- } else {
- glDisable(GL_LIGHTING);
- }
-
- }
-
- static void
- drawMaterialMeter(void)
- {
- if (useLighting) glDisable(GL_LIGHTING);
-
- glPushMatrix();
- glLoadIdentity();
- glTranslatef(0.7, -0.9, -1.0);
- glScalef(0.2, 1.8, 1.0);
-
- glBegin(GL_LINES);
- glIndexf(0.95*indexScale);
- glVertex2f(0.0, 0.0); glVertex2f(1.0, 0.0);
- glVertex2f(1.0, 0.0); glVertex2f(1.0, 1.0);
- glVertex2f(1.0, 1.0); glVertex2f(0.0, 1.0);
- glVertex2f(0.0, 1.0); glVertex2f(0.0, 0.0);
-
- glIndexf(0.25*indexScale);
- glVertex2f(0.0, matIndexRange[0]); glVertex2f(1.0, matIndexRange[0]);
-
- glIndexf(0.50*indexScale);
- glVertex2f(0.0, matIndexRange[1]); glVertex2f(1.0, matIndexRange[1]);
-
- glIndexf(0.75*indexScale);
- glVertex2f(0.0, matIndexRange[2]); glVertex2f(1.0, matIndexRange[2]);
- glEnd();
-
- glPopMatrix();
-
- if (useLighting) glEnable(GL_LIGHTING);
- }
-
- static void
- drawGrid(void)
- {
- static int dlist = 0;
-
- if (dlist) {
- glCallList(dlist);
- } else {
- int u = 8, v = 8;
- float du = 1.0 / u;
- float dv = 1.0 / v;
- int i, j;
-
- dlist = glGenLists(1);
- glNewList(dlist, GL_COMPILE_AND_EXECUTE);
-
- glNormal3f(0.0, 0.0, 1.0);
- glBegin(GL_QUADS);
- for (j=0; j<v; ++j) {
- float y = j * dv;
-
- for (i=0; i<u; ++i) {
- float x = i * du;
-
- if ((i ^ j) & 1) {
- glIndexf(0.25*indexScale);
- } else {
- glIndexf(0.75*indexScale);
- }
- glVertex2f(x , y );
- glVertex2f(x+du, y );
- glVertex2f(x+du, y+dv);
- glVertex2f(x , y+dv);
- }
- }
- glEnd();
-
- glEndList();
- }
- }
-
- static void
- drawCylinder(void)
- {
- static int dlist = 0;
-
- if (dlist) {
- glCallList(dlist);
- } else {
- int u = 16;
- float du = (2*M_PI) / u;
- int i, j;
-
- dlist = glGenLists(1);
- glNewList(dlist, GL_COMPILE_AND_EXECUTE);
-
- glBegin(GL_TRIANGLE_STRIP);
- for (i=0; i<=u; ++i) {
- float t = i * du;
- float x = 0.5 * (float)cos((double) t) + 0.5;
- float y = 0.5 * (float)sin((double) t) + 0.5;
-
- glNormal3f(2.0 * (x - 0.5), 2.0 * (y - 0.5), 0.0);
- glIndexf(0.80*indexScale);
- glVertex3f(x, y, 0.5);
- glIndexf(0.20*indexScale);
- glVertex3f(x, y, -0.5);
- }
- glEnd();
-
- glEndList();
- }
- }
-
- #define NUM_OBJECTS 2
- static void (*drawObject[NUM_OBJECTS])(void) = { drawGrid, drawCylinder };
-
- static void
- redraw(float xrot, float yrot)
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- drawMaterialMeter();
-
- glPushMatrix();
- glRotatef(xrot, 1, 0, 0);
- glRotatef(yrot, 0, 1, 0);
-
- glPushMatrix();
- glScalef(1.5, 1.5, 1.25);
- glTranslatef(-0.5, -0.5, 0.0);
- (*drawObject[whichObject])();
- glPopMatrix();
-
- glPopMatrix();
- }
-
- static Colormap
- buildGrayScaleColormap(Display *dpy, XVisualInfo *vis)
- {
- Colormap cmap;
-
- cmap = XCreateColormap(dpy, RootWindow(dpy, vis->screen),
- vis->visual, AllocNone);
-
- if (vis->class == PseudoColor) {
- int mapSize = 1 << vis->depth;
- int firstEntry = 0;
- int entry;
- unsigned long *pix;
-
- pix = (unsigned long *) calloc(mapSize, sizeof(unsigned long));
-
- if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pix, mapSize)) {
- if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pix, mapSize-1)) {
- fprintf(stderr, "can't alloc enough colormap entries\n");
- exit(EXIT_FAILURE);
- }
- firstEntry = 1;
- }
-
- for (entry=firstEntry; entry<mapSize; ++entry) {
- XColor col;
- int val = entry * (0xffff / (mapSize-1));
-
- col.pixel = entry;
- col.red = val;
- col.green = val;
- col.blue = val;
- col.flags = DoRed | DoGreen | DoBlue;
-
- XStoreColor(dpy, cmap, &col);
- }
-
- free((void *) pix);
- } else {
- fprintf(stderr, "can't build colormap for selected visual\n");
- exit(EXIT_FAILURE);
- }
-
- return cmap;
- }
-
- static Bool
- waitForMapNotify(Display *dpy, XEvent *ev, XPointer arg)
- {
- return ((ev->type == MapNotify) && (ev->xmapping.window == (Window) arg));
- }
-
- static int visualAttrs[] = {
- GLX_DOUBLEBUFFER,
- GLX_BUFFER_SIZE, 4,
- GLX_DEPTH_SIZE, 1,
- GLX_LEVEL, 0,
- None,
- };
-
- int
- main(int argc, char **argv)
- {
- Display *dpy;
- int scrn;
- Window root;
- XVisualInfo *vis;
- GLXContext ctx;
- Colormap cmap;
- XSizeHints sizehints;
- XSetWindowAttributes swa;
- Window win;
- XEvent ev;
- char *name = "ColorIndex Lighting";
- char *geometry = NULL;
- int x = 0;
- int y = 0;
- unsigned int width = 300;
- unsigned int height = 300;
- int needsReconfig = 1;
- int needsRedraw = 1;
- int done = 0;
- float xrot = 0.0;
- float yrot = 0.0;
- int x0, y0;
- int i;
-
- for (i=1; i<argc; ++i) {
- if ((strcmp("-geometry", argv[i]) == 0) && (i+1 < argc)) {
- geometry = argv[++i];
- }
- }
-
- if ((dpy = XOpenDisplay(NULL)) == NULL) {
- fprintf(stderr, "can't open display\n");
- exit(EXIT_FAILURE);
- }
- scrn = DefaultScreen(dpy);
- root = RootWindow(dpy, scrn);
-
- if ((vis = glXChooseVisual(dpy, scrn, visualAttrs)) == NULL) {
- fprintf(stderr, "can't find visual\n");
- exit(EXIT_FAILURE);
- }
-
- if ((ctx = glXCreateContext(dpy, vis, NULL, True)) == NULL) {
- fprintf(stderr, "can't create context\n");
- exit(EXIT_FAILURE);
- }
-
- sizehints.flags = PPosition | PSize;
- sizehints.width = (int) width;
- sizehints.height = (int) height;
- sizehints.x = x;
- sizehints.y = y;
- if (geometry) {
- int flags = XParseGeometry(geometry, &x, &y, &width, &height);
-
- if (flags & WidthValue) {
- sizehints.flags |= USSize;
- sizehints.width = (int) width;
- }
- if (flags & WidthValue) {
- sizehints.flags |= USSize;
- sizehints.height = (int) height;
- }
- if (flags & XValue) {
- if (flags & XNegative) {
- x = DisplayWidth(dpy, scrn) + x - sizehints.width;
- }
- sizehints.flags |= USPosition;
- sizehints.x = x;
- }
- if (flags & YValue) {
- if (flags & YNegative) {
- y = DisplayHeight(dpy, scrn) + y - sizehints.height;
- }
- sizehints.flags |= USPosition;
- sizehints.y = y;
- }
- }
-
- cmap = buildGrayScaleColormap(dpy, vis);
-
- swa.colormap = cmap;
- swa.background_pixel = None;
- swa.border_pixel = None;
- win = XCreateWindow(dpy, root,
- sizehints.x, sizehints.y,
- sizehints.width, sizehints.height, 0,
- vis->depth, InputOutput, vis->visual,
- CWColormap | CWBackPixel | CWBorderPixel, &swa);
-
- XSetStandardProperties(dpy, win, name, name, None, argv, argc, &sizehints);
-
- XSelectInput(dpy, win,
- StructureNotifyMask | ExposureMask |
- KeyPressMask | ButtonPressMask | ButtonMotionMask);
-
- XMapWindow(dpy, win);
- XIfEvent(dpy, &ev, waitForMapNotify, (XPointer) win);
-
- glXMakeCurrent(dpy, win, ctx);
-
- indexScale = (1 << vis->depth) - 1;
- init();
-
- while (!done) {
- do {
- XNextEvent(dpy, &ev);
- switch (ev.type) {
- case KeyPress:
- {
- KeySym ks;
- float p;
-
- XLookupString(&ev.xkey, NULL, 0, &ks, NULL);
- switch (ks) {
- case XK_Escape:
- done = 1;
- break;
- case XK_O: case XK_o:
- whichObject = (whichObject + 1) % NUM_OBJECTS;
- break;
- case XK_L: case XK_l:
- useLighting = !useLighting;
- break;
- case XK_T: case XK_t:
- useTwoSide = !useTwoSide;
- break;
- case XK_K: case XK_k:
- useLocalLight = !useLocalLight;
- break;
- case XK_V: case XK_v:
- useLocalViewer = !useLocalViewer;
- break;
- case XK_P: case XK_p:
- useSpot = !useSpot;
- break;
- case XK_N: case XK_n:
- useAtten = !useAtten;
- break;
- case XK_A:
- p = matIndexRange[0] + 0.005;
- if (p < 0.0) p = 0.0;
- if (p > 1.0) p = 1.0;
- matIndexRange[0] = p;
- break;
- case XK_a:
- p = matIndexRange[0] - 0.005;
- if (p < 0.0) p = 0.0;
- if (p > 1.0) p = 1.0;
- matIndexRange[0] = p;
- break;
- case XK_D:
- p = matIndexRange[1] + 0.005;
- if (p < 0.0) p = 0.0;
- if (p > 1.0) p = 1.0;
- matIndexRange[1] = p;
- break;
- case XK_d:
- p = matIndexRange[1] - 0.005;
- if (p < 0.0) p = 0.0;
- if (p > 1.0) p = 1.0;
- matIndexRange[1] = p;
- break;
- case XK_S:
- p = matIndexRange[2] + 0.005;
- if (p < 0.0) p = 0.0;
- if (p > 1.0) p = 1.0;
- matIndexRange[2] = p;
- break;
- case XK_s:
- p = matIndexRange[2] - 0.005;
- if (p < 0.0) p = 0.0;
- if (p > 1.0) p = 1.0;
- matIndexRange[2] = p;
- break;
- default:
- break;
- }
- }
- needsReconfig = 1;
- needsRedraw = 1;
- break;
- case ButtonPress:
- x0 = ev.xbutton.x;
- y0 = ev.xbutton.y;
- break;
- case MotionNotify:
- yrot += (float)(ev.xmotion.x-x0) * (360.0 / (float) width);
- if (yrot > 360) yrot = yrot - 360;
- if (yrot < 0) yrot = 360 - yrot;
-
- xrot += (float)(ev.xmotion.y-y0) * (360.0 / (float) height);
- if (xrot > 360) xrot = xrot - 360;
- if (xrot < 0) xrot = 360 - xrot;
-
- x0 = ev.xmotion.x; y0 = ev.xmotion.y;
- needsRedraw = 1;
- break;
- case ConfigureNotify:
- width = (unsigned int) ev.xconfigure.width;
- height = (unsigned int) ev.xconfigure.height;
- needsReconfig = 1;
- needsRedraw = 1;
- break;
- case Expose:
- default:
- needsRedraw = 1;
- break;
- }
- } while (XPending(dpy));
-
- if (needsReconfig) {
- glViewport(0, 0, (float) width, (float) height);
- reconfig();
- needsReconfig = 0;
- }
-
- if (needsRedraw) {
- redraw(xrot, yrot);
- glXSwapBuffers(dpy, win);
- needsRedraw = 0;
- }
- }
- }
-